import React, { Component, PureComponent } from "react";

class DemoComponent extends PureComponent {
    state = {
        arr: [1,2,3],
    };
    render() {
        let { arr } = this.state;
        return (
            <>
                {
                  arr.map((item, index) => {
                      return (
                          <span key={index} style={{
                              display: "inline-block",
                              width: 100,
                              height: 100,
                              backgroundColor: "blue",
                              marginRight: 10,
                              color: "#fff",
                          }}>
                              {item}
                          </span>
                      );
                  })
                }
                <br />
                <button onClick={() => {
                    arr.push(4);
                    this.setState(
                      {
                        arr: [...arr],
                      }
                    );
                }}>add span</button>
            </>
        )
    };

    /**
     * PureComponent原理
     *  shouldComponentUpdate(nextProps, nextState) {
            let { props, state } = this;
            return !objectShallowEqual(props, nextProps) || !objectShallowEqual(state, nextState);
        };
     */
    
};

export default DemoComponent;
/**
 * PureComponent和Component的区别
 *    PureComponent会给类组件自动添加shouldComponentUpdate周期函数，并对新老属性/状态做浅比较
 *    如果经过浅比较发现属性/状态并没有改变，则返回false，不会更新组件
 */


/**
 * 封装对象浅比较的方法
 */
// 判断是否为对象且不为null
const isObject = function isObject(obj) {
    return obj !== null && /^(function|object)$/.test(typeof obj);
};

// objectShallowEqual方法
const objectShallowEqual = function objectShallowEqual(objA, objB) {
    // 如果objA 或者 objB 不是对象 返回false
    if (!isObject(objA) || !isObject(objB)) return false;
    // 如果objA 和 objB 相等 返回true
    if (objA === objB) return true;
    // 先比较对象属性成员的数量
    let keysA = Reflect.ownKeys(objA),
        keysB = Reflect.ownKeys(objB);
    if (keysA.length !== keysB.length) return false;
    // 数量一致的话再逐一比较内部成员[只比较第一级，浅比较]
    for (let i = 0; i < keysA.length; i++) {
        let key = keysA[i];
        // 如果一个对象中有这个成员，另一个对象中没有这个成员，或者两个对象中都有这个成员，但是值不相同"Object.is(NaN, NaN) === true"，都应该判定为不相同 
        if (!objB.hasOwnProperty(key) || !Object.is(objA[key], objB[key])) {
          return false;
        } 
    }; 
    // 以上都处理完，没有发现不同的成员，则认为两个对象是相等的（浅比较）
    return true;
};

let obj = {
    x: 10,
};

let objA = {
    a: 10,
    b: obj,
    c: [1, 2, 3],
};

obj.y = 20;
let objB = {
    d: 10,
    b: obj,
    c: [1, 2, 3],
};

let objC = {
    a: 10,
    b: obj,
};

let objD = {
    a: 10,
    b: obj,
};

// console.log(objectShallowEqual(objA, objB));
// console.log(objectShallowEqual(objC, objD));
